home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
FIREWALL.ZIP
/
FIREWALL.ASM
< prev
next >
Wrap
Assembly Source File
|
1996-06-03
|
10KB
|
182 lines
;FIREWALL.ASM by Tanjent, a.k.a. Austin Appleby
;
;Hello, hello, and welcome to the program that never ends... <grin>
;Well, until you hit a key, anyway... This is my own personal version
;of the now-overused flame algorithm, doctored up a bit and made to
;run in 320x200 because I'm too lazy to learn mode X programming. Besides,
;it looks a lot better without all its pixels doubled/quadrupled/whatever.
;This is my first program written in all Assembly, which I guess isn't bad
;since I've known this language a whole of, what, 2 weeks now? I've
;documented just about everything in there, because I remember how hard
;it was for me to read my first bit of code, even with documentation.
;So, better overkill than underkill . This whole mess has even been
;optimized a bit, though I imagine it can be sped up even more. This method
;is the best overall of the ones I've tried so far, nice clean code and
;fairly good speed (I could speed it up by unrolling the smooth loop 4
;steps and writing pixels in one nice stosd, but that doesn't save me
;enough clocks to merit the added code messiness.
;
; For those poor souls among you who don't already know how a fire
;algorithm works, here's my very brief description - Set each pixel in the
;screen buffer equal to the average of some of its surrounding pixels, set
;the bottom line of the buffer to a random line of pixels, repeat ad
;nauseam. I'm using the following weighted average for my algorithm -
;
; ...#... - Current pixel being computed
; ...A...
; ..BCD..
; .......
;
;where the pixel being computed = ((16*A)+(14*C)+B+D)/32
; This average gives nice, semi-round flames, and only takes a SHL
;and two SUBs more than a standard average (and it looks a lot nicer too).
;
;Any questions can be sent to me at appleby@mail.utexas.edu, and if you
;notice any ways to speed up this code PLEASE PLEASE tell me about them.
;I've gone through umpteen methods of rewriting this thing in trying to
;make it faster, and this is the fastest of the ones I've written so far.
;Farewell, and happy coding...
DOSSEG
.MODEL SMALL
.STACK 200h
.DATA
INCLUDE rand.lst
INCLUDE fire.pal
.CODE
.386
Ideal
PROC InitScrn NEAR ;The Screen Initter. What a great name.
;I think I'll name my firstborn son Initter.
;It's just such a cool name, don't you think?
xor eax,eax ;Clear out those registers, just in case.
xor di,di ;
mov bx,ss ;Fetch the Stack Segment... Why, you ask?
;Well, the DOSSEG up at the top says that
;the segments in this program are going to be
;ordered with the stack segment last. So,
;we're fetching that segment address so we can
;set up a chunk of memory after it to use
;as a screen buffer.
add bx,20h ;Our stack is 200h bytes, so scoot up
;the segment index by enough so we're not
;overlapping it.
mov cx,16240 ;We're using a buffer with 320*203 bytes,
;that's so we can stick the random dots
;offscreen and make it look a bit nicer.
;320*203 < 65536, so we'll still be able to get
;everything inside the same segment.
mov es,bx ;Make this our destination
rep stosd ;Fill it with a bunch of zeroes!
mov ax,es ;Swap that over to DS, since we'll need to
mov ds,ax ;read from it later.
mov ax,0A000h ;And put A000h, the screen segment, into ES.
mov es,ax ;
ret
ENDP InitScrn
PROC Smooth NEAR ;The Screen Smoother. It's slow, slow, slow.
mov ecx,64000 ;64000 pixels to smooth
mov edi,0 ;DS:EDI = current pixel
mov esi,641 ;DS:ESI = Pixel that needs to be loaded
;the other two are kept in EAX
xor eax,eax ;Clear any stuff out of EAX before we begin
smoothloop:
mov bl,[ds:edi+320] ;Fetch the pixel that's a line below our current
;pixel, this is pixel A in the diagram
add bx,ax ;Add the pixel we saved from last time to BX
;This is pixel C in the diagram above
shl bx,4 ;Multiply BX by 16 (A+C)*16=16*A+16*C
sub bx,ax ;Subtract AX twice, 16*A+16*C-C-C=
sub bx,ax ; 16*A+14*C
ror eax,16 ;Swap the high and low words of EAX
add bx,ax ;Add the value that was in the high word
;This is pixel B in the diagram.
lodsb ;Load pixel D from memory
add bx,ax ;Add it to BX, now we have 16*A+14*C+B+D in BX
shr bx,5 ;Divide BX by 32 to get an average
mov [ds:edi],bl ;Save the low byte into our buffer
inc di ;Increment our current pixel index
loop smoothloop ;Lather, rinse, repeat until done.
ret
ENDP Smooth
PROC DumpScrn NEAR ;The Screen Dumper.
mov cx,16000 ;Very simple screen dump, DS=buffer
xor di,di ;& ES=A000h=screen. Gotta clear those
xor si,si ;offsets first though...
rep movsd ;I like rep movsd. Do you?
ret
ENDP DumpScrn
PROC RandLine NEAR ;The Random Line Drawer.
push ds ;Save our segments, we're gonna screw
push es ;with em'
mov ax,ds ;Fetch DS, the buffer segment
add ax,4000 ;Scoot it up by 4000*16=64000 bytes,
;so we point at a line that's offscreen.
mov es,ax ;Put it in our destination segment
mov ax,seg Rand ;Fetch the segment of our random table
mov ds,ax ;Make it our source segment
xor ax,ax ;Clear AX of those nasty residues
mov al,[ebx] ;set AL to a value in the random table
;with the index EBX
mov si,ax ;Make that random value our random table
;index so the random line jumps around
mov di,10 ;Start writing at 10 pixels from the left edge
mov cx,300 ;we'll be writing 300 pixels
rep movsb ;and copy those 300 pixels from the rand table
mov si,ax ;Reset our random table index
add di,20 ;Scoot around so we're back under the first
;line of random pixels
mov cx,300 ;write 300 more
rep movsb ;and copy them. Simple eh?
pop es ;Restore our original segments.
pop ds ;Weehoo weehoo.. i love comments.. <gag>
ret
ENDP RandLine
START: ;Guess.
mov al,0013h ;Jump into mode 13h, 320x200x256 colors.
int 10h ;using Int 10h
mov dx,seg FirePal ;Fetch our palette segment into DS
mov ds,dx ;
mov si,offset FirePal ;And get the offset too.
mov dx,03c8h ;Tell the vidcard at port 3c8 that we want to
xor al,al ;write the palette starting at color 0
out dx,al ;by dumping 0 to that port.
inc dx ;Now we want to dump to port 3c9.
mov cx,256*3 ;We'll be dumping 256 colors * 3 values per
;color (R,G,B)
rep outsb ;Lather, rinse, repeat.
call InitScrn ;Go set up our screen buffer.
xor ebx,ebx ;Clear out EBX, we'll be using it as a counter
;so we get a different line of random pixels
;from RandLine
looper: ;This is the loop that makes things boogie.
call RandLine ;Draw some random pixels in there
push bx ;Save our counter
call Smooth ;Smooth the buffer
mov dx,3dah ;Vertical Retrace Checking - port 3DAh
V1: in al,dx ;I'm waiting on a baby VRT... won't my mommy
test al,8 ;be so proud of me... <grin> All this bit
jnz V1 ;does is check the video card to see
V2: in al,dx ;if it's trying to update the screen,
test al,8 ;and if it is we wait until it's done.
jz V2 ;
call DumpScrn ;Dump it to the screen
pop bx ;Restore the counter
inc bl ;and increment it.
mov ah,01 ;Test to see if some fool pressed a key
int 16h ;with int 16h, subfunction 1.
jz looper ;If they didn't, keep going.
mov ax,0003h ;If they did, go back to text mode (3)
int 10h ;with int 10h
mov ax,4c00h ;and return control to DOS. (whew!)
int 21h ;with good ol' int 21.
END START